
import java.io.File;

import java.io.*;
import java.util.ArrayList;
import java.util.Scanner;


public class TestRecommender {
	
	private static DatabaseConnector dbConn;
    
    private static int counter;	
	
    public static void main(String[] args)
    {    	
    	dbConn = new DatabaseConnector();
    	//uploadUserData();
        //Users evaluated
        
        //EVAL data
        //uploadKaggleData();
    	
    	RecommendData();
        
        dbConn.close();
    }
	
    public static void uploadUserData()
    {
    	User listener = new User("");
    	
    	//Open file
    	File userData = new File( "train_triplets3.txt");
    	try
    	{
    		Scanner scanner = new Scanner( new FileReader(userData) );
	        try 
	        {
	          int i =0;
	          counter = 0;
	          
			  while ( scanner.hasNextLine() ){
			  //for (int i=0; i< 1000; i++){
				listener = readUser( listener , scanner.nextLine() );	
				i++;
			  }
			  System.out.println("Lines of user data: " + i);
	        }
	        finally
	        {
	        	scanner.close();
	        }  
    	}
    	catch (Exception e) 
    	{
    		e.printStackTrace();
    		System.out.println("Invalid File: train triples"); 
    	}
    	
    }
    
    public static void RecommendData()
    {
    	User listener = null;
    	User newListener = null;
    	
    	//Open file
    	File userData = new File( "kaggle_visible_evaluation_triplets.txt");

    	try
    	{
        	FileWriter outFile = new FileWriter("recommendations.txt");
        	
        	Scanner scanner = new Scanner( new FileReader(userData) );
    		  BufferedWriter out = new BufferedWriter(outFile);
    		  
    		  //Close the output stream
    		  //Close the output stream

	        try 
	        {
	          //first use a Scanner to get each line
	          counter = 0;
	          while ( scanner.hasNextLine() ){
	        	  
	        	  newListener = readUser( listener , scanner.nextLine() );	
	        	  
	        	  if ( (listener != null) && (newListener != null) && (newListener.name != listener.name) )
	        	  {
	        		  //listener is done. OK to Recommend
	        		  makeRecommendations( listener, out);
	        		  counter++;
	        	  }
	        	  listener = newListener;
	          }
	        }
	        finally
	        {
	        	scanner.close();
	        	out.close();
	        }  
    	}
    	catch (Exception e) 
    	{
    		System.out.println("Invalid File");
    		e.printStackTrace();
    	}
    	
    }    
    
    public static void makeRecommendations( User listener, BufferedWriter out )
    {
    	try
    	{
    		int bestCluster = -1;
    		double highPref = -1;
    		for (int i=0; i<10; i++)
    		{
    			if ( listener.preferences[i] > highPref)
    			{
    				highPref = listener.preferences[i];
    				bestCluster = i;    				
    			}		
    		}
    		
    		ArrayList<RecommendedSong> bestSongs = 
				dbConn.getMaxScoringSongs( listener, bestCluster, (counter<25) );
    		
    		if ( bestSongs.size() > 0)
    		{
    			out.write( String.format("%d", bestSongs.get(0).SongIndex ) );
    		}
    		for (int i =1; i< Math.min(500,bestSongs.size()) ; i++)
    		{
    			out.write( String.format(" %d", bestSongs.get(i).SongIndex ) );
    		}
    		out.write("\n");
    		
    		
    	}catch (Exception e)
    	{
    		System.out.println( "recommend fail");
    		e.printStackTrace();
    	}
    }
    
    public static User readUser( User listener, String listenData )
    {    	
    	String[] data = listenData.split("\t");
    	
    	//System.out.println( "LINE: " + data );
    	
    	String songID = data[1];
    	int count = Integer.parseInt(data[2]);
    	int cluster = dbConn.getCluster( songID );
    	
    	if ( cluster != -1 )
    	{
    		//System.out.println("SONG FOUND");
	    	if ( (listener != null) && data[0].equals( listener.name ) )
	    	{    		
	    		//TODO remove
	    		listener.name = data[0];
	    		
	    		//add pheromones
	    		ArrayList<Double> pheromones = dbConn.getPheromones( songID );
	    		AntSystem syst = new AntSystem(count, listener.listenCount, 
	    										listener.preferences, pheromones );
	    		ArrayList<Double> newPheromones = syst.updatePheros();
	    		dbConn.setPheromones( songID, newPheromones);
	    		
	    		//adjust preferences with normalize
	    		listener.UpdatePreferences( cluster, count );
	    	}
	    	else
	    	{
	    		counter++;
	    		if (counter > 100)
	    		{
		    		counter =0;
		    		System.out.println("End user: " + listener.listenCount);
	    		}
	    		
	    		//new user
	    		
	    		listener = new User(data[0]);
	    		listener.listenCount = count;
	    		listener.preferences[cluster] = 1;
	    		//don't add pheromones
	    	}
    	}
    	else
    	{
    		//System.out.println("missed song");
    		
    	}
    	
    	return listener;
    }
    
    public static void uploadKaggleData()
    {
    	File userData = new File( "kaggle_songs.txt");
    	try
    	{
    		Scanner scanner = new Scanner( new FileReader(userData) );
	        try 
	        {
	          //first use a Scanner to get each line
	          while ( scanner.hasNextLine() ){
	        	  String[] data = (scanner.nextLine()).split(" ");
	        	  dbConn.setSongIndex( data[0], data[1]);	        	  
	          }
	        }
	        finally
	        {
	        	scanner.close();
	        }
    	}
    	catch (Exception e) 
    	{
    		System.out.println("Invalid Kaggle File"); 
    		e.printStackTrace();
    	}
    	
    }
    
}
